package top.atcra.rpc.protection.loadBalancer;

import io.netty.channel.Channel;
import top.atcra.rpc.discovery.register.ServiceRegistry;
import top.atcra.rpc.protection.loadBalancer.selector.impl.ConsistentHashSelector;
import top.atcra.rpc.protection.loadBalancer.selector.impl.MinResponseTimeSelector;
import top.atcra.rpc.protection.loadBalancer.selector.impl.RoundRobinServiceSelector;

import java.util.TreeMap;

public class LoadBalancerFactory {

    public static LoadBalancer getLoadBalancer(ServiceRegistry registry, LoadBalanceType type) {
        return switch (type) {
            case round_robin -> new LoadBalancer(registry, RoundRobinServiceSelector::new);
            case consistent_hash -> new LoadBalancer(registry, ConsistentHashSelector::new);
            case null, default -> throw new IllegalArgumentException("Unknown load balancer type: " + type);
        };
    }

    public static LoadBalancer getLoadBalancer(ServiceRegistry registry, byte typeId) {
        return getLoadBalancer(registry, LoadBalanceType.valueOf(typeId));
    }

    public static LoadBalancer getMinResponseTimeLoadBalancer(ServiceRegistry registry, TreeMap<Long, Channel> TTLCache) {
        var loadBalancer = new LoadBalancer(registry, (addresses) -> {
            var selector = new MinResponseTimeSelector(addresses);
            selector.setTTLCache(TTLCache);
            return selector;
        });
        return loadBalancer;
    }
}
